package admin

import (
	"end/config"
	"end/entry"
	"end/httpEntry"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"net/http"
	"time"
)

type UserDto struct {
	Id                int       `json:"id" gorm:"column:id"`
	Name              string    `json:"name" gorm:"column:name"`
	Nick              string    `json:"nick" gorm:"column:nick"`
	Img               string    `json:"img" gorm:"column:img"`
	Age               int       `json:"age" gorm:"column:age"`
	Phone             string    `json:"phone" gorm:"column:phone"`
	PoliticalOutlook  string    `json:"political-outlook" gorm:"column:political_outlook"`
	Address           string    `json:"address" gorm:"column:address"`
	PersonalSignature string    `json:"personal_signature" gorm:"column:personal_signature"`
	CreateTime        time.Time `json:"createtime" gorm:"column:createtime"`
	UpdateTime        time.Time `json:"updatetime" gorm:"column:updatetime"`
}

func (UserDto) TableName() string {
	return "user"
}

type Dto struct {
	Id         int       `json:"id" gorm:"column:id"`
	UserID     int       `json:"userid" gorm:"column:userid"`
	Power      int       `json:"power" gorm:"column:power"`
	CreateTime time.Time `json:"createtime" gorm:"column:createtime"`
	Belong     string    `json:"belong" gorm:"column:belong"`
	Phone      string    `json:"phone" gorm:"column:phone"`
	StartTime  string    `json:"starttime" gorm:"column:starttime"`
	EndTime    string    `json:"endtime" gorm:"column:endtime"`
	Status     string    `json:"status" gorm:"column:status"`
	User       UserDto
}

func (Dto) TableName() string {
	return "admin"
}

type DelRequest struct {
	Id int `json:"id" binding:"required"`
}

type AllRequest struct {
	Page  int `json:"page" binding:"required"`
	Power int `json:"power"`
}

// AddAdmin 申请管理员
func AddAdmin(r *gin.Engine) {

	type AddRequest struct {
		Belong    string `json:"belong" binding:"required"`
		Phone     string `json:"phone" binding:"required"`
		Starttime string `json:"starttime" binding:"required"`
		Endtime   string `json:"endtime" binding:"required"`
		Power     int    `json:"power" binding:"required"`
	}

	r.POST("/add/admin", httpEntry.LoginMiddleware(), httpEntry.Admin1Middleware(), func(context *gin.Context) {
		var addRequest AddRequest
		err := context.ShouldBind(&addRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		var admin entry.Admin
		err = copier.Copy(&admin, addRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		var user entry.User
		db := config.GetDb()
		db.Where("phone = ?", addRequest.Phone).First(&user)
		admin.UserID = user.ID
		admin.Power = addRequest.Power
		admin.CreateTime = time.Now()
		admin.Phone = addRequest.Phone
		result := db.Create(&admin)
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10026,
				Error: httpEntry.ERROR10026,
			})
			return
		}
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "成功",
			"admin":   admin,
		})
	})
}

// UpdateAdmin 修改管理员信息
func UpdateAdmin(r *gin.Engine) {
	type Request struct {
		Phone     string `json:"phone" binding:"required"`
		Belong    string `json:"belong" binding:"required"`
		Starttime string `json:"starttime" binding:"required"`
		Endtime   string `json:"endtime" binding:"required"`
		Id        int    `json:"id" binding:"required"`
	}

	r.POST("/admin/update", httpEntry.LoginMiddleware(), httpEntry.Admin1Middleware(), func(context *gin.Context) {
		var request Request
		err := context.ShouldBind(&request)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		db := config.GetDb()
		toMap, err := config.UpdateToMap(&request)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		result := db.Model(&entry.Admin{}).Where("id = ?", request.Id).Updates(toMap)
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "更新成功",
		})
	})
}

// AllAdmin 查看全部管理员
func AllAdmin(r *gin.Engine) {
	r.POST("/admin/all", httpEntry.LoginMiddleware(), httpEntry.AdminMiddleware(), func(context *gin.Context) {
		var allRequest AllRequest
		err := context.ShouldBind(&allRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		db := config.GetDb()
		var admins []Dto
		if allRequest.Power == 0 {
			result := db.Preload("User").
				Offset((allRequest.Page - 1) * 20).
				Limit(20).
				Order("admin.createtime desc").
				Find(&admins)
			if result.Error != nil {
				context.JSON(http.StatusOK, httpEntry.BaseResponse{
					Code:  10005,
					Error: httpEntry.ERROR10005,
				})
				return
			}
		} else {
			result := db.Preload("User").Where("power = ?", allRequest.Power).
				Offset((allRequest.Page - 1) * 20).
				Limit(20).
				Order("admin.createtime desc").
				Find(&admins)
			if result.Error != nil {
				context.JSON(http.StatusOK, httpEntry.BaseResponse{
					Code:  10005,
					Error: httpEntry.ERROR10005,
				})
				return
			}
		}

		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取成功",
			"data":    admins,
		})
	})
}

// DelAdmin 删除管理员
func DelAdmin(r *gin.Engine) {
	r.POST("/admin/del", httpEntry.LoginMiddleware(), httpEntry.Admin1Middleware(), func(context *gin.Context) {
		db := config.GetDb()
		var delRequest DelRequest
		err := context.ShouldBind(&delRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		result := db.Delete(&entry.Admin{}, delRequest.Id)
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10009,
			})
			return
		}
		context.JSON(http.StatusOK, httpEntry.BaseResponse{
			Code:    200,
			Message: "删除成功",
		})
	})
}

type AuditAdminRequest struct {
	Adminid int `json:"adminid" binding:"required"`
	Num     int `json:"num" binding:"required"`
}

// InfoALlAdmin 管理员信息
func InfoALlAdmin(r *gin.Engine) {
	r.GET("/admin/info/all", httpEntry.LoginMiddleware(), httpEntry.AdminMiddleware(), func(context *gin.Context) {
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		db := config.GetDb()
		var activityNum int64
		var allPeople int64
		db.Model(entry.Activity{}).Where("admin_id = ? and status = ?", userinfo.Id, httpEntry.STATUS2).Count(&activityNum)
		db.Model(entry.Eventregistration{}).Where("adminid = ? and status != ?", userinfo.Id, httpEntry.STATUS1).Count(&allPeople)
		var admin entry.Admin
		db.Where("id = ?", userinfo.Id).First(&admin)
		context.JSON(http.StatusOK, gin.H{
			"code":        200,
			"activityNum": activityNum,
			"allPeople":   allPeople,
			"power":       admin.Power,
			"admin":       admin,
		})
	})
}

// IsAdmin 管理员检测函数
func IsAdmin(r *gin.Engine) {
	r.GET("/admin/detection", httpEntry.LoginMiddleware(), httpEntry.AdminMiddleware(), func(context *gin.Context) {
		context.JSON(http.StatusOK, httpEntry.BaseResponse{
			Code:    200,
			Message: "我是管理员",
		})
	})
}

type AllBusinessRequest struct {
	Page   int `json:"page"`
	Status int `json:"status"`
}

func AllBusiness(r *gin.Engine) {
	r.POST("/admin/business/all", httpEntry.LoginMiddleware(), httpEntry.AdminMiddleware(), func(context *gin.Context) {
		var allRequest AllBusinessRequest
		err := context.ShouldBind(&allRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		db := config.GetDb()
		var business []entry.Business
		db.Where("status & ?", allRequest.Status).
			Offset((allRequest.Page - 1) * 20).
			Limit(20).
			Order("createtime desc").
			Find(&business)
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "成功",
			"data":    business,
		})
	})
}
